package com.hy.mydesktop.client.component.factory;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import com.extjs.gxt.samples.resources.client.Resources;
import com.extjs.gxt.samples.resources.client.TestData;
import com.extjs.gxt.samples.resources.client.model.Folder;
import com.extjs.gxt.ui.client.data.BaseListLoadResult;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.dnd.DND.Feedback;
import com.extjs.gxt.ui.client.dnd.GridDragSource;
import com.extjs.gxt.ui.client.dnd.GridDropTarget;
import com.extjs.gxt.ui.client.store.GroupingStore;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.widget.form.StoreFilterField;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.EditorGrid;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.grid.GridGroupRenderer;
import com.extjs.gxt.ui.client.widget.grid.GroupColumnData;
import com.extjs.gxt.ui.client.widget.grid.GroupingView;
import com.extjs.gxt.ui.client.widget.grid.RowEditor;
import com.extjs.gxt.ui.client.widget.grid.RowNumberer;
import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;
import com.extjs.gxt.ui.client.widget.treegrid.EditorTreeGrid;
import com.extjs.gxt.ui.client.widget.treegrid.TreeGrid;
import com.extjs.gxt.ui.client.widget.treegrid.TreeGridCellRenderer;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.hy.mydesktop.shared.persistence.domain.gxt.GxtComponentMetaNodeModel;
import com.test.client.component.meta.GridModelEnum;
import com.test.client.rpc.GreetingService;
import com.test.client.rpc.GreetingServiceAsync;
import com.test.client.rpc.ServiceInvoker;
import com.test.client.rpc.ServiceInvokerAsync;

/**
 * 
 * <ul>
 * <li>开发作者：冬超</li>
 * <li>设计日期：2010-8-30；时间：下午01:11:56</li>
 * <li>类型名称：ReorderingGridFactory</li>
 * <li>设计目的：</li>
 * </ul>
 * <ul>
 * <b>修订编号：</b>
 * <li>修订日期：</li>
 * <li>修订作者：</li>
 * <li>修订原因：</li>
 * <li>修订内容：</li>
 * </ul>
 */
public class GridFactory {
	private static List<ColumnConfig> configs;
	private static GridCellRenderer<ModelData> ageRender;
	private static TreeGridCellRenderer<ModelData> treeRender;
	private static GridDropTarget dropTarget;
	private static RpcProxy<List<ModelData>> proxy;
	private static ColumnModel cm;

	public static Grid<ModelData> createReorderingGrid(
			GxtComponentMetaNodeModel gxtComponentMetaNodeModel) {

		return configureReorderingGrid(gxtComponentMetaNodeModel);

	}

	
	private static Grid<ModelData> configureReorderingGrid(
			GxtComponentMetaNodeModel gxtComponentMetaNodeModel) {

		Grid<ModelData> grid = createDefaultBaseGrid((Integer) gxtComponentMetaNodeModel
				.get(GridModelEnum.VERSION.name().toLowerCase()));

		if (gxtComponentMetaNodeModel.get(GridModelEnum.HIGHT.name()
				.toLowerCase()) != null) {
			Integer height = (Integer) gxtComponentMetaNodeModel
					.get(GridModelEnum.HIGHT.name().toLowerCase());
			grid.setHeight((int) height);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.WIDTH.name()
				.toLowerCase()) != null) {
			Integer width = (Integer) gxtComponentMetaNodeModel
					.get(GridModelEnum.WIDTH.name().toLowerCase());
			grid.setWidth((int) width);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.ENABLECOLUMNRESIZE
				.name().toLowerCase()) != null) {
			Boolean enableColumnResize = (Boolean) gxtComponentMetaNodeModel
					.get(GridModelEnum.ENABLECOLUMNRESIZE.name().toLowerCase());
			grid.setEnableColumnResize(enableColumnResize);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.MINCOLUMNWIDTH.name()
				.toLowerCase()) != null) {
			Integer minColumnWidth = (Integer) gxtComponentMetaNodeModel
					.get(GridModelEnum.MINCOLUMNWIDTH.name().toLowerCase());
			grid.setMinColumnWidth(minColumnWidth);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.AUTOEXPANDCOLUMN.name()
				.toLowerCase()) != null) {
			String autoColumn = (String) gxtComponentMetaNodeModel
					.get(GridModelEnum.AUTOEXPANDCOLUMN.name().toLowerCase());
			grid.setAutoExpandColumn(autoColumn);

		}
		// 需要把方filter加到面板上才能够使用
		if (gxtComponentMetaNodeModel.get(GridModelEnum.FILTER.name()
				.toLowerCase()) != null) {
			StoreFilterField<ModelData> filter = new StoreFilterField<ModelData>() {

				@Override
				protected boolean doSelect(Store<ModelData> store,
						ModelData parent, ModelData record, String property,
						String filter) {
					// only match leaf nodes
					if (record instanceof Folder) {
						return false;
					}
					String name = record.get("name");
					name = name.toLowerCase();
					if (name.startsWith(filter.toLowerCase())) {
						return true;
					}
					return false;
				}

			};
			TreeStore<ModelData> treeStore = getTreeStore();
			filter.bind(treeStore);

		}

		if (gxtComponentMetaNodeModel.get(GridModelEnum.TRACKMOUSEOVER.name()
				.toLowerCase()) != null) {
			Boolean trackMouseOver = (Boolean) gxtComponentMetaNodeModel
					.get(GridModelEnum.TRACKMOUSEOVER.name().toLowerCase());
			grid.setTrackMouseOver(trackMouseOver);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.BORDER.name()
				.toLowerCase()) != null) {
			Boolean show = (Boolean) gxtComponentMetaNodeModel
					.get(GridModelEnum.BORDER.name().toLowerCase());
			grid.setBorders(show);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.NUMBER.name()
				.toLowerCase()) != null) {
			Integer number = (Integer) gxtComponentMetaNodeModel
					.get(GridModelEnum.NUMBER.name().toLowerCase());
			int version = gxtComponentMetaNodeModel.get(GridModelEnum.VERSION
					.name().toLowerCase());
			getField(configs, ageRender, number, version);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.ROEWEDIT.name()
				.toLowerCase()) != null) {
			RowEditor<ModelData> editor = new RowEditor<ModelData>();
			grid.addPlugin(editor);
		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.REODRDER.name()
				.toLowerCase()) != null) {
			dropTarget = new GridDropTarget(grid);
			new GridDragSource(grid);
		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.GRIDNUMBER.name()
				.toLowerCase()) != null) {
			RowNumberer numberer = new RowNumberer();
			grid.addPlugin(numberer);
		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.GROUPINGVIEW.name()
				.toLowerCase()) != null) {
			GroupingView view = new GroupingView();
			view.setShowGroupedColumn(false);
			view.setForceFit(true);
			view.setGroupRenderer(new GridGroupRenderer() {
				public String render(GroupColumnData data) {
					return null;
				}
			});
			grid.setView(view);
		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.FEEBACK.name()
				.toLowerCase()) != null) {
			String back = ((String) gxtComponentMetaNodeModel
					.get(GridModelEnum.FEEBACK.name().toLowerCase()))
					.toUpperCase();
			if (back.equals("APPEND")) {
				dropTarget.setFeedback(Feedback.APPEND);
			} else if (back.equals("BOTH")) {
				dropTarget.setFeedback(Feedback.BOTH);
			} else {
				dropTarget.setFeedback(Feedback.INSERT);
			}

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.AllOWSELFASSOURCE
				.name().toLowerCase()) != null) {
			Boolean allowSelfAsSource = (Boolean) gxtComponentMetaNodeModel
					.get(GridModelEnum.AllOWSELFASSOURCE.name().toLowerCase());
			dropTarget.setAllowSelfAsSource(allowSelfAsSource);
		}

		return grid;
	}

	private static Grid<ModelData> createDefaultBaseGrid(int version) {

		final ListStore<ModelData> employeeStore = getListStore();
		TreeStore<ModelData> treestore = getTreeStore();
		GroupingStore<ModelData> groupStore = getGroupStore();
		ListStore<ModelData> pagingStore = getPaging();
		
		List<ColumnConfig> col = new ArrayList<ColumnConfig>();
		ColumnConfig column = new ColumnConfig();
		column.setId("name");
		column.setHeader("Make");
		column.setWidth(150);
		col.add(column);
		column = new ColumnConfig();
		column.setId("age");
		column.setHeader("Model");
		column.setWidth(120);
		col.add(column);
		
		configs = new ArrayList<ColumnConfig>();

		cm = new ColumnModel(col);
		if (version == 1) {
			// 可编辑的表格
			/**
			 * 
			 * ServiceInvokerAsync serviceInvoker = GWT.create(ServiceInvoker.class);
			 * serviceInvoker.invokeService(className, serviceName, parameterList, callback);
			 * 传什么样的参数
			 * 调用哪个类的哪个方法
			 * 解析：
			 * 例如，想要查询人员列表，需要得到List<BaseModel>
			 * 就需要有类PersonService类，和listPerson方法
			 * 参数，暂时为空
			 * 
			 */
			/*ServiceInvokerAsync serviceInvoker = GWT.create(ServiceInvoker.class);
			serviceInvoker.invokeService("com.test.server.business.PersonService", "listPerson",new AsyncCallback<List<BaseModel>>() {
				
				@Override
				public void onSuccess(List<BaseModel> result) {
					System.out.println(result+"++++++++++++++++++++++");
					List<BaseModel> bmBaseModels= new LinkedList<BaseModel>();
					for (Object object : result) {
						bmBaseModels.add((BaseModel)object);
					}
					employeeStore.add((List<BaseModel>)bmBaseModels);
				}
				
				@Override
				public void onFailure(Throwable caught) {
					System.out.println("-----------------++++++++++++++++++++++");
					caught.printStackTrace();
				}
			});*/
				
			/*GreetingServiceAsync service = GWT.create(GreetingService.class);
			 service.getBaseModle(null, new AsyncCallback<List<BaseModel>>() {
				
				@Override
				public void onSuccess(List<BaseModel> result) {
				
					employeeStore.add(result);
				}
				
				@Override
				public void onFailure(Throwable caught) {
					caught.printStackTrace();
				}
			});*/
			EditorGrid<ModelData> grid = new EditorGrid<ModelData>(
					employeeStore, cm);
			return grid;
		}
		
		if (version == 2) {
			// 分组表格
			Grid<ModelData> grid = new Grid<ModelData>(groupStore, cm);
			return grid;
		}
		if (version == 3) {
			// 分页表格
			Grid<ModelData> grid = new Grid<ModelData>(pagingStore, cm);
			return grid;
		} 
		if (version == 4) {
			// 可编辑的树形表格
			EditorTreeGrid<ModelData> grid = new EditorTreeGrid<ModelData>(
					treestore, cm);
			
			return grid;
		}
		if (version == 5) {
			// 普通树形表格
			TreeGrid<ModelData> grid = new TreeGrid<ModelData>(treestore, cm);
			
			return grid;
		}
		else {
			// 普通表格
			Grid<ModelData> grid = new Grid<ModelData>(employeeStore, cm);
			return grid;
		}
	}

	// 表格的字段
	private static List<ColumnConfig> getField(List<ColumnConfig> configs,
			GridCellRenderer<ModelData> ageRender, int number, int version) {
		for (int i = 0; i < number; i++) {
			ColumnConfig name = new ColumnConfig();
			name.setId("jjjj");
			name.setHeader("jjjj");
			name.setWidth(100);
			if (version < 4) {
				name.setRenderer(ageRender);
			} else {
				name.setRenderer(treeRender);
			}
			configs.add(name);
		}
		return configs;
	}

	// 普通表格的后台数据
	private static ListStore<ModelData> getListStore() {
		proxy = new RpcProxy<List<ModelData>>() {
			@Override
			protected void load(Object loadConfig,
					AsyncCallback<List<ModelData>> callback) {
				// GreetingServiceAsync service = GWT.create(GreetingService.class);
				 //service.getBaseModle(null, callback);
			}
		};

		ListLoader<BaseListLoadResult<ModelData>> loader = new BaseListLoader<BaseListLoadResult<ModelData>>(
				proxy);
		ListStore<ModelData> employeeStore = new ListStore<ModelData>(loader);
		ageRender = new GridCellRenderer<ModelData>() {
			@Override
			public Object render(ModelData model, String property,
					com.extjs.gxt.ui.client.widget.grid.ColumnData config,
					int rowIndex, int colIndex, ListStore<ModelData> store,
					Grid<ModelData> grid) {
				return null;
			}
		};
		return employeeStore;
	}

	// 树形表格的后台数据
	private static TreeStore<ModelData> getTreeStore() {
		Folder model = TestData.getTreeModel();
		TreeStore<ModelData> treeStore = new TreeStore<ModelData>();
		treeStore.add(model.getChildren(), true);
		treeRender = new TreeGridCellRenderer<ModelData>();
		return treeStore;
	}

	// 分组表格的后台数据
	private static GroupingStore<ModelData> getGroupStore() {
		GroupingStore<ModelData> store = new GroupingStore<ModelData>();
		store.add(TestData.getCompanies());
		store.groupBy("industry");
		return store;
	}

	//分页表格的后台数据
	private static ListStore<ModelData> getPaging() {
		proxy = new RpcProxy<List<ModelData>>() {
			@Override
			protected void load(Object loadConfig,
					AsyncCallback<List<ModelData>> callback) {
				// DataServiceAsync service = GWT.create(DataService.class);
				// service.readData(callback);
			}
		};
		PagingLoader<PagingLoadResult<ModelData>> loader = new BasePagingLoader<PagingLoadResult<ModelData>>(
				proxy);
		loader.setRemoteSort(true);

		ListStore<ModelData> store = new ListStore<ModelData>(loader);
		// 需要把toolbar加到面板上
		PagingToolBar toolBar = new PagingToolBar(50);
		toolBar.bind(loader);
		return store;
	}

}
